package com.qiaofang.applet.service.property.service.impl;

import com.google.common.collect.Lists;
import com.qiaofang.applet.common.base.MongoBaseService;
import com.qiaofang.applet.common.context.QfContext;
import com.qiaofang.applet.common.context.QfContextHolder;
import com.qiaofang.applet.common.exception.BusinessException;
import com.qiaofang.applet.constants.PhotoCategoryConstants;
import com.qiaofang.applet.service.other.domain.CityCompany;
import com.qiaofang.applet.service.other.domain.PropertyWaterMark;
import com.qiaofang.applet.service.other.repository.CityCompanyRepository;
import com.qiaofang.applet.service.property.domain.EstateAlbum;
import com.qiaofang.applet.service.property.domain.EstateAlbumPhoto;
import com.qiaofang.applet.service.property.domain.EstatePhoto;
import com.qiaofang.applet.service.property.repository.EstateAlbumPhotoRepository;
import com.qiaofang.applet.service.property.repository.EstateAlbumRepository;
import com.qiaofang.applet.service.property.service.CommonService;
import com.qiaofang.applet.service.property.service.EstateAlbumPhotoService;
import com.qiaofang.applet.service.property.service.dto.*;
import com.qiaofang.applet.service.property.service.mapstruct.EstateAlbumPhotoMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class EstateAlbumPhotoServiceImpl extends MongoBaseService<EstateAlbumPhoto, String> implements EstateAlbumPhotoService {

    private final EstateAlbumPhotoRepository repository;

    @Autowired
    public EstateAlbumPhotoServiceImpl(EstateAlbumPhotoRepository repository) {
        super(repository);
        this.repository = repository;
    }

    @Autowired
    private EstateAlbumRepository estateAlbumRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private EstateAlbumPhotoMapper estateAlbumPhotoMapper;

    @Autowired
    private CommonService commonService;

    @Autowired
    private CityCompanyRepository cityCompanyRepository;

    /**
     * 获取类目列表
     *
     * @param estateUniqueUuid
     * @return
     */
    @Override
    public List<EstateAlbumDto> getAlbums(String estateUniqueUuid) {
        List<EstateAlbumDto> result = new LinkedList<>();
        List<EstateAlbum> list = estateAlbumRepository.findAllByEstateUniqueUuid(estateUniqueUuid)
                .stream().sorted(Comparator.comparing(EstateAlbum::getUpdateTime)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(list)) {
            for (EstateAlbum estateAlbum : list) {
                Query query = new Query();
                query.addCriteria(Criteria.where("albumId").is(estateAlbum.getId()));
                Long count = mongoTemplate.count(query, EstateAlbumPhoto.class);
                result.add(EstateAlbumDto.builder()
                        .id(estateAlbum.getId())
                        .typeName(estateAlbum.getTypeName())
                        .estateUniqueUuid(estateAlbum.getEstateUniqueUuid())
                        .photoNum(count.intValue())
                        .sort(estateAlbum.getSort())
                        .build());
            }
        }
        return result;
    }

    /**
     * 保存类目
     *
     * @param estateAlbumDto
     */
    @Override
    public void saveAlbum(EstateAlbumDto estateAlbumDto) {
        String id = estateAlbumDto.getId();
        String typeName = estateAlbumDto.getTypeName();
        String estateUniqueUuid = estateAlbumDto.getEstateUniqueUuid();
        EstateAlbum estateAlbum = estateAlbumRepository.findByEstateUniqueUuidAndTypeName(estateUniqueUuid, typeName);
        if (StringUtils.isEmpty(id) && estateAlbum == null) {
            estateAlbum = new EstateAlbum();
            estateAlbum.setEstateUniqueUuid(estateUniqueUuid);
            estateAlbum.setTypeName(typeName);
            estateAlbum.setSort(estateAlbumDto.getSort());
        } else if (!StringUtils.isEmpty(id) && (estateAlbum == null || id.equals(estateAlbum.getId()))) {
            estateAlbum = new EstateAlbum();
            estateAlbum.setId(id);
            estateAlbum.setEstateUniqueUuid(estateUniqueUuid);
            estateAlbum.setTypeName(typeName);
            estateAlbum.setSort(estateAlbumDto.getSort());
        } else {
            throw new BusinessException("类目名称重复，保存失败");
        }
        estateAlbumRepository.save(estateAlbum);
    }

    /**
     * 删除类目
     *
     * @param albumId
     */
    @Override
    public void deleteAlbum(String albumId) {
        estateAlbumRepository.deleteById(albumId);
        repository.deleteAllByAlbumId(albumId);
    }

    /**
     * 获取类目图片
     *
     * @param albumId
     * @return
     */
    @Override
    public Map<String, List<EstateAlbumPhotoDto>> getAlbumPhotos(String albumId) {
        /**
         * 1.查询property_estate_album_photo表（EstateAlbumPhoto）获取当前类目下所有图片
         * 2.根据categoryName的类型（waijing 外景  shinei 室内  other 其他）组装参数
         * 3.返回值map的key值参考PhotoCategoryConstants类的中文文字，其中"全部"key对应的list等于其他三个list总和
         */
        Map<String, List<EstateAlbumPhotoDto>> resultMap = new HashMap<>();
        //全部
        List<EstateAlbumPhoto> allAlbumPhotoList = repository.findAllByAlbumId(albumId);
        List<EstateAlbumPhotoDto> estateAlbumPhotoDtos = estateAlbumPhotoMapper.domainToListDto(allAlbumPhotoList);
        //分组
        Map<String, List<EstateAlbumPhotoDto>> categoryNameMap = estateAlbumPhotoDtos.stream().collect(Collectors.groupingBy(EstateAlbumPhotoDto::getCategoryName));
        resultMap.put("all", estateAlbumPhotoDtos);
        resultMap.putAll(categoryNameMap);
        return resultMap;
    }

    @Override
    public Map<String, List<EstateAlbumPhotoDto>> getMiniAlbumPhotos(List<EstateAlbumDto> estateAlbumDtoList) {
        if (CollectionUtils.isEmpty(estateAlbumDtoList)){
            return null;
        }
        Map<String, List<EstateAlbumPhotoDto>> resultMap = new HashMap<>();
        //该类目id下所有的照片
        for (EstateAlbumDto estateAlbumDto : estateAlbumDtoList) {
            List<EstateAlbumPhoto> allAlbumPhotoList = repository.findAllByAlbumId(estateAlbumDto.getId());
            List<EstateAlbumPhotoDto> estateAlbumPhotoDtos = estateAlbumPhotoMapper.domainToListDto(allAlbumPhotoList);
            resultMap.put(estateAlbumDto.getTypeName(),estateAlbumPhotoDtos);
        }
        return resultMap;
    }

    /**
     * 获取可添加类目图片
     *
     * @param estateAlbumPhotoToAddDto
     * @return
     */
    @Override
    public Map<String, List<EstatePhotoDto>> getAddiblePhotos(EstateAlbumPhotoToAddDto estateAlbumPhotoToAddDto) {
        /**
         * 1.查询property_estate_album_photo表（EstateAlbumPhoto）获取当前类目下所有图片的photoUuid集合（用分组查询取特定字段）
         * 2.查询property_estate_photo表（EstatePhoto）获取可添加的小区图片list 【查询条件：排除掉的uuid集合，排除category为"fangxing"】
         * 3.根据categoryName的类型（waijing 外景  shinei 室内  other 其他）组装参数
         * 4.返回值map的key值参考PhotoCategoryConstants类的中文文字，其中"全部"key对应的list等于其他三个list总和
         */
        //已添加类型下的图片uuid
        List<String> photoUuids = repository.findAllByAlbumId(estateAlbumPhotoToAddDto.getAlbumId()).stream().map(EstateAlbumPhoto::getPhotoUuid).collect(Collectors.toList());
        Map<String, List<EstatePhotoDto>> resultMap = new HashMap<>();
        Query query = new Query().addCriteria(Criteria.where("estateUniqueUuid").is(estateAlbumPhotoToAddDto.getEstateUniqueUuid()));
        query.addCriteria(Criteria.where("photoUuid").nin(photoUuids));
        Criteria criteria = new Criteria();
        criteria.orOperator(Criteria.where("categoryName").is(PhotoCategoryConstants.INDOOR_PHOTO.getCategory()),
                Criteria.where("categoryName").is(PhotoCategoryConstants.OUTDOOR_PHOTO.getCategory()),
                Criteria.where("categoryName").is(PhotoCategoryConstants.OTHER.getCategory()));
        query.addCriteria(criteria);

        List<EstatePhoto> estatePhotos = mongoTemplate.find(query, EstatePhoto.class);
        List<EstatePhotoDto> estatePhotoDtoList = estateAlbumPhotoMapper.domainListToListDto(estatePhotos);

        Map<String, List<EstatePhotoDto>> otherPhotoMap = Optional.ofNullable(estatePhotoDtoList).orElseGet(Lists::newArrayList)
                .stream().collect(Collectors.groupingBy(EstatePhotoDto::getCategoryName));
        resultMap.putAll(otherPhotoMap);
        resultMap.put("all", estatePhotoDtoList);
        return resultMap;
    }

    /**
     * 批量新增类目图片
     *
     * @param addListDto
     */
    @Override
    public void addAlbumPhotos(EstateAlbumPhotoAddListDto addListDto) {
        List<EstateAlbumPhotoAddDto> list = addListDto.getAddList();
        if (!CollectionUtils.isEmpty(list)) {
            List<EstateAlbumPhoto> estateAlbumPhotoList = new ArrayList<>(list.size());
            Set<String> photoUuids = new HashSet<>();
            for (EstateAlbumPhotoAddDto estateAlbumPhotoAddDto : list) {
                String photoUuid = estateAlbumPhotoAddDto.getPhotoUuid();
                if (photoUuids.contains(photoUuid)) {
                    continue;
                }
                photoUuids.add(photoUuid);
                EstateAlbumPhoto estateAlbumPhoto = repository.findByAlbumIdAndPhotoUuid(addListDto.getAlbumId(), photoUuid);
                if (estateAlbumPhoto != null) {
                    continue;
                }
                estateAlbumPhoto = new EstateAlbumPhoto();
                estateAlbumPhoto.setAlbumId(addListDto.getAlbumId());
                estateAlbumPhoto.setPhotoUuid(photoUuid);
                estateAlbumPhoto.setPhotoURL(estateAlbumPhotoAddDto.getPhotoURL());
                estateAlbumPhoto.setCategoryName(estateAlbumPhotoAddDto.getCategoryName());
                estateAlbumPhotoList.add(estateAlbumPhoto);
            }
            if (!CollectionUtils.isEmpty(estateAlbumPhotoList)) {
                repository.saveAll(estateAlbumPhotoList);
            }
        }
    }


    /**
     * 编辑类目图片说明、标签
     *
     * @param estateAlbumPhotoEditDto
     */
    @Override
    public void editAlbumPhoto(EstateAlbumPhotoEditDto estateAlbumPhotoEditDto) {
        EstateAlbumPhoto estateAlbumPhoto = new EstateAlbumPhoto();
        estateAlbumPhoto.setId(estateAlbumPhotoEditDto.getId());
        estateAlbumPhoto.setExplain(estateAlbumPhotoEditDto.getExplain());
        estateAlbumPhoto.setTags(estateAlbumPhotoEditDto.getTags());
        updateById(estateAlbumPhoto);
    }


    /**
     * 移除类目图片
     *
     * @param id
     */
    @Override
    public void deleteAlbumPhoto(String id) {
        repository.deleteById(id);
    }

    @Override
    public Map<String, List<EstateAlbumPhotoDto>> getAlbumPhotosByAlbumId(EstatePhotoQueryDto estatePhotoQueryDto) {
        Map<String, List<EstateAlbumPhotoDto>> resultMap = null;
        try {
            resultMap = new HashMap<>();
            //当前相册下的 所有照片
            List<EstateAlbumPhoto> photoList = repository.findAllByAlbumId(estatePhotoQueryDto.getAlbumId());

            PropertyWaterMark propertyWaterMark = getPropertyWaterMark();
            for (EstateAlbumPhoto photo : photoList) {
                photo.setPhotoURL(commonService.propertyWaterMark(photo.getPhotoURL(), propertyWaterMark));
            }

            List<EstateAlbumPhotoDto> estateAlbumPhotoDtos = estateAlbumPhotoMapper.domainToListDto(photoList);
            EstateAlbum estateAlbum = estateAlbumRepository.findByEstateUniqueUuidAndId(estatePhotoQueryDto.getEstateUniqueUuid(), estatePhotoQueryDto.getAlbumId());
            resultMap.put(estateAlbum.getTypeName(),estateAlbumPhotoDtos);
        } catch (Exception e) {
         log.error("小程序获取小区相册详情异常 : {}");
        }
        return resultMap;
    }

    /**
     * 获取公司水印设置
     * @return
     */
    private PropertyWaterMark getPropertyWaterMark() {
        QfContext context = QfContextHolder.getContext();
        List<CityCompany> cityCompanyList = cityCompanyRepository.findAllByCorporationCodeAndCityCodeAndMainCityFlag(context.getCorporationCode(), context.getCityCode(), 1);
        if (CollectionUtils.isEmpty(cityCompanyList)) {
            return null;
        }
        return cityCompanyList.get(0).getPropertyWaterMark();
    }
}
